#include "pch.hpp"
#include "RenderNode.hpp"

using namespace Engine;
using namespace Engine::Video;




RenderNode::RenderNode(const Effect::ptr& effect)
	: transparent(false)
	, effect(effect)
	, technique("")
	, distance(0)
{}
///////////////////////////////////////////////////////////////////////////////////////////////////

void RenderNode::post_create(ptr _this)
{}
///////////////////////////////////////////////////////////////////////////////////////////////////

RenderNode::~RenderNode()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




RenderPass& RenderNode::pass(const std::string& name)
{
	foreach(RenderPass& pass, passes)
	{
		if(pass.name == name)
			return pass;
	}

	BOOSTEXT_THROW(critical_exception(format("There is no pass named '%1%'") % name));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

const RenderPass& RenderNode::pass(const std::string& name) const
{
	foreach(const RenderPass& pass, passes)
	{
		if(pass.name == name)
			return pass;
	}

	BOOSTEXT_THROW(critical_exception(format("There is no pass named '%1%'") % name));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void RenderNode::addPass(const RenderPass& pass)
{
	passes.push_back(pass);
	// TODO: adjust transparency
	transparent = false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void RenderNode::swap(RenderNode& right)
{
	technique.swap(right.technique);
	std::swap(distance, right.distance);

	std::swap(transparent, right.transparent);
	effect.swap(right.effect);
	std::swap(passes, right.passes);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool RenderNode::sort(const RenderNode& left, const RenderNode& right)
{
	if(left.transparent && !right.transparent)
	{
		return false;
	}
	else if(right.transparent && !left.transparent)
	{
		return true;
	}
	else if(!left.transparent && !right.transparent)
	{
		return left.distance > right.distance;
	}
	else if(left.transparent && right.transparent)
	{
		return left.distance < right.distance;
	}

	return (left.distance > right.distance);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool RenderNode::sort_ptr(const RenderNode::ptr& left, const RenderNode::ptr& right)
{
	return sort(*left, *right);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool Engine::Video::operator < (const RenderNode& left, const RenderNode& right)
{
	return RenderNode::sort(left, right);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

bool Engine::Video::operator < (const RenderNode::ptr& left, const RenderNode::ptr& right)
{
	return *left < *right;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
